﻿using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Linq;

namespace HobSoft.SoccerBet2014.Domain.Common.BfApi
{
    using Models.BfRaw;
    public class ApiBettingRestClient : ApiRestClient
    {
        protected const string LIST_MARKET_BOOK = "listMarketBook";
        protected const string PLACE_ORDERS = "placeOrders";
        protected const string CANCEL_ORDERS = "cancelOrders";
        protected const string LIST_CURRENT_ORDERS = "listCurrentOrders";
        public ApiBettingRestClient(string key, string token)
            : base(key, token)
        {
        }

        protected override string EndPoint
        {
            get { return @"https://api.betfair.com/exchange/betting/rest/v1.0/"; }
        }

        public async Task<IList<MarketBook>> ListMarketBook(IEnumerable<string> _marketIds)
        {
            var result = await PostAsync(LIST_MARKET_BOOK, new ApiJsonContent
            {
                Params = new
                {
                    marketIds = _marketIds.ToArray(),
                    priceProjection = new PriceProjection
                    {
                        ExBestOffersOverrides = new ExBestOffersOverrides { },
                        PriceData = new HashSet<PriceData> { PriceData.EX_BEST_OFFERS },
                        //RolloverStakes = true,
                        Virtualise = true
                    },
                    orderProjection = OrderProjection.ALL,
                    matchProjection = MatchProjection.NO_ROLLUP
                    //currencyCode = "",
                    //local = ""
                }
            });
            return JsonConvert.DeserializeObject<IList<MarketBook>>(result);
        }

        public async Task<PlaceExecutionReport> Betting(string _marketId, IList<PlaceInstruction> _placeInstructions, string _customerRef = null)
        {
            var result = await PostAsync(PLACE_ORDERS, new ApiJsonContent
            {
                Params = new
                {
                    marketId = _marketId,
                    instructions = _placeInstructions,
                    customerRef = _customerRef
                }
            });
            return (PlaceExecutionReport)JsonConvert.DeserializeObject<PlaceExecutionReport>(result);
        }

        public async Task<PlaceExecutionReport> Betting(string _marketId, PlaceInstruction _placeInstruction, string _customerRef = null)
        {
            var result = await PostAsync(PLACE_ORDERS, new ApiJsonContent
            {
                Params = new
                {
                    marketId = _marketId,
                    instructions = new List<PlaceInstruction>() { _placeInstruction },
                    customerRef = _customerRef
                }
            });
            return (PlaceExecutionReport)JsonConvert.DeserializeObject<PlaceExecutionReport>(result);
        }

        public async Task<CurrentOrderSummaryReport> ListOrders(ISet<string> betIds = null,
                                                        ISet<string> marketIds = null,
                                                        OrderProjection? orderProjection = null,
                                                        TimeRange placedDateRange = null,
                                                        TimeRange dateRange = null,
                                                        OrderBy? orderBy = null,
                                                        SortDir? sortDir = null,
                                                        int? fromRecord = null,
                                                        int? recordCount = null)
        {
            var result = await PostAsync(LIST_CURRENT_ORDERS, new ApiJsonContent
            {
                Params = new
                {
                    betIds = betIds.ToArray(),
                    marketIds = marketIds.ToArray(),
                    orderProjection = orderProjection,
                    placedDateRange = placedDateRange,
                    dateRange = dateRange,
                    orderBy = orderBy,
                    sortDir = sortDir,
                    fromRecord = fromRecord,
                    recordCount = recordCount
                }
            });
            return JsonConvert.DeserializeObject<CurrentOrderSummaryReport>(result);
        }

        public async Task<CurrentOrderSummaryReport> ListOrders()
        {
            var result = await PostAsync(LIST_CURRENT_ORDERS, new ApiJsonContent
            {
                Params = new
                {
                    //betIds = betIds.ToArray(),
                    //marketIds = marketIds.ToArray(),
                    orderProjection = OrderProjection.ALL,
                    //placedDateRange = placedDateRange,
                    //dateRange = dateRange,
                    orderBy = OrderBy.BY_BET,
                    sortDir = SortDir.EARLIEST_TO_LATEST,
                    //fromRecord = fromRecord,
                    //recordCount = recordCount
                }
            });
            return JsonConvert.DeserializeObject<CurrentOrderSummaryReport>(result);
        }

        public async Task<CancelExecutionReport> CancelOrders(string _marketId, CancelInstruction _instruction, string _customerRef)
        {
            var result = await PostAsync(CANCEL_ORDERS, new ApiJsonContent
            {
                Params = new
                {
                    marketId = _marketId,
                    instructions = new List<CancelInstruction>() { _instruction },
                    customerRef = _customerRef
                }
            });
            return JsonConvert.DeserializeObject<CancelExecutionReport>(result);
        }
    }
}
